﻿using NAudio.Vorbis;
using NAudio.Wave;
using Shell32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using 旧式 = System.Windows.Forms;


namespace 无缝播放器
{
    /// <summary>
    ///  访问音频信息
    /// </summary>
    public class 音频信息
    {
        public bool 提示窗打开 { get; set; } = false;
        public int 当前段编号 { get; set; } = 0;
        public int 下一段编号 { get; set; } = 1;
        public int 默认BPM { get; set; } = 400;
        public int 当前段BPM { get; set; } = 60;
        public int 当前段起始点 { get; set; } = 0;
        public int 当前段拍数 { get; set; } = 4;
        public int 循环次数 { get; set; } = 0;
        public int 当前小节 { get; set; } = 0;
        public int 当前拍 { get; set; } = 0;
        public int 淡入_字节修改量 { get; set; } = 0;
        public int 淡出_字节修改量 { get; set; } = 0;
        public int 每采样字节 { get; set; } = 10;
        public int 线程号 = 0;
        public int 播放总长度 = 0;
        public bool 切换点在末拍 = false;
        public int 当前UI绑定线程 = 0;
        public double 每拍Bit { get; set; } = -1;
        public double 当前播放位置 = 0;
        public double 每拍毫秒 { get; set; } = -1;

        public double 当前播放字节 { get; set; } = 0;
        public long 偏移 { get; set; } = 0;
        /// <summary>
        /// 控制字节流是否还需要读入数据到播放器，若关闭，字节流将立刻停止发送数据造成终止
        /// 和“字节流移交”不同的是，“仍需读取流”不会持续播放完剩下的字节流。
        /// </summary>
        public bool 仍需读取流 { get; set; } = true;
        public bool 播完停止 { get; set; } = false;
        public bool 播放下一拍后跳转 { get; set; } = false;
        public bool 已在淡入 = false;
        public bool 已在淡出 = false;
        /// <summary>
        ///  控制字节流的移交状态，若为true，说明该字节流已移交，将在播放完剩下的字节流后结束播放。
        ///  和“仍需读取流”不同的是，“字节流移交”仍会持续播放完剩下的字节流。
        /// </summary>
        public bool 字节流移交 { get; set; } = false;
        public bool 有过渡音频 { get; set; } = false;
        public bool 等待效果音 { get; set; } = false;
        public ArrayList 节拍特例 { get; set; } = new ArrayList();
        public List<int> 循环文件下标 { get; set; } = new List<int>();
        public ArrayList 章节信息 { get; set; } = new ArrayList();
        public 循环类型 循环方法 { get; set; } = 循环类型.未定义;
        public enum 循环类型
        {
            未定义,
            不可循环,
            仅无缝循环,
            交互式无缝循环,
        }
        public 音频状态 播放状态 { get; set; } = 音频状态.未定义;
        public enum 音频状态
        {
            静音,
            满音量,
            淡入中,
            淡出中,
            未定义,
            播放中,
            暂停中,
            停止中,
        }
    }
    /// <summary>
    ///  访问器材信息
    /// </summary>
    public class 器材
    {

        public List<WaveChannel32> 读取器组 { get; set; } = new List<WaveChannel32>();
        public List<VorbisWaveReader> obb读取器组 { get; set; } = new List<VorbisWaveReader>();
        public List<MemoryStream> 内存文件组 { get; set; } = new List<MemoryStream>();
        public List<WaveOutEvent> 播放器组 { get; set; } = new List<WaveOutEvent>();
        public WaveOut 过渡播放器 { get; set; } = new WaveOut();
        public AudioFileReader 过渡文件音频文件读取器 { get; set; } = null;
        VorbisWaveReader 使用reader { get; set; } = null;
        public string 过渡音频 { get; set; } = null;
        
    }
    public class 流
    {
        public List<音频流> 文件 { get; set; } = new List<音频流>();

    }
    class 读配置文件
    {
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
        [DllImport("kernel32")]
        private static extern int WritePrivateProfileString(string lpApplicationName, string lpKeyName, string lpString, string lpFileName);
        /// <summary>
        ///读取一个配置项，如果这个配置项中的值不存在返回一个默认值
        /// </summary>
        /// <param name="配置节名">配置节名</param>
        /// <param name="配置项名">配置项名</param>
        /// <param name="默认返回">如果这个配置项中的值不存在返回一个默认值</param>
        /// <param name="配置项文件">指定一个配置项的文件路径</param>
        /// <returns></returns>
        public string 读配置项(string 配置项文件, string 配置节名, string 配置项名, string 默认返回)
        {
            if (File.Exists(配置项文件))
            {
                StringBuilder temp = new StringBuilder(1024);
                GetPrivateProfileString(配置节名, 配置项名, 默认返回, temp, 1024, 配置项文件);
                return temp.ToString();
            }
            else
            {
                return 默认返回;
            }
        }

    }
    class 图标按钮
    {
        public const string 文件集 = "🗃";
        public const string 普通 = "💿";
        public const string 永续 = "♾️";
        public const string 可操作 = "🔃";
        static public string 形成图文(string 图标按钮, string 文本)
        {
            string 格式 = null;
            if (文本.Contains("mp3"))
            {
                格式 = "mp3";
            }
            if (文本.Length > 15)
            {
                文本 = 文本.Substring(0, 15) + "...";
                if (格式 != null)
                {
                    文本 += "mp3";
                }
            }

            return $"{图标按钮} {文本}";
        }
    }
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //初始化信息类
        音频信息 信息 = new 音频信息();
        器材 器材 = new 器材();
        //文件初始化
        string 当前文件夹路径 = "";
        ArrayList 文件夹名称组 = new ArrayList();
        ArrayList 文件夹路径组 = new ArrayList();
        ArrayList 文件名 = new ArrayList();
        static List<string> 播放列表 = new List<string>();
        static List<int> 循环文件下标 = null;
        static ArrayList 节拍特例;
        Dictionary<string, string> 对应表 = new Dictionary<string, string>();
        Dictionary<string, string> UI对应表 = new Dictionary<string, string>();
        Dictionary<string, string> 过渡文件 = new Dictionary<string, string>();
        Dictionary<string, string> 配置文件 = new Dictionary<string, string>();
        static bool MP3文件 = false;
        static bool 手动停止 = false;
        static bool 正在拖动进度条 = false;
        时钟壁纸应用.主要窗口.窗口状态 控件;
        //与线程有关
        AudioFileReader MP3读取器;
        流 流 = new 流();

        public string[] ReadMp3(string path)
        {
            int mp3TagID = 0;
            string[] tags = new string[6];
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[10];
            // fs.Read(buffer, 0, 128);
            string mp3ID = "";

            fs.Seek(0, SeekOrigin.Begin);
            fs.Read(buffer, 0, 10);
            int size = (buffer[6] & 0x7F) * 0x200000 + (buffer[7] & 0x7F) * 0x400 + (buffer[8] & 0x7F) * 0x80 + (buffer[9] & 0x7F);
            //int size = (buffer[6] & 0x7F) * 0X200000 * (buffer[7] & 0x7f) * 0x400 + (buffer[8] & 0x7F) * 0x80 + (buffer[9]);
            mp3ID = Encoding.Default.GetString(buffer, 0, 3);
            if (mp3ID.Equals("ID3", StringComparison.OrdinalIgnoreCase))
            {
                mp3TagID = 1;
                //如果有扩展标签头就跨过 10个字节
                if ((buffer[5] & 0x40) == 0x40)
                {
                    fs.Seek(10, SeekOrigin.Current);
                    size -= 10;
                }
                tags = ReadFrame(fs, size);
            }
            return tags;
        }
        public string[] ReadFrame(FileStream fs, int size)
        {
            string[] ID3V2 = new string[6];
            byte[] buffer = new byte[10];
            while (size > 0)
            {
                //fs.Read(buffer, 0, 1);
                //if (buffer[0] == 0)
                //{
                //    size--;
                //    continue;
                //}
                //fs.Seek(-1, SeekOrigin.Current);
                //size++;
                //读取标签帧头的10个字节
                fs.Read(buffer, 0, 10);
                size -= 10;
                //得到标签帧ID
                string FramID = Encoding.Default.GetString(buffer, 0, 4);
                //计算标签帧大小，第一个字节代表帧的编码方式
                int frmSize = 0;

                frmSize = buffer[4] * 0x1000000 + buffer[5] * 0x10000 + buffer[6] * 0x100 + buffer[7];
                if (frmSize == 0)
                {
                    //就说明真的没有信息了
                    break;
                }
                //bFrame 用来保存帧的信息
                byte[] bFrame = new byte[frmSize];
                fs.Read(bFrame, 0, frmSize);
                size -= frmSize;
                string str = GetFrameInfoByEcoding(bFrame, bFrame[0], frmSize - 1);
                if (FramID.CompareTo("TIT2") == 0)
                {
                    ID3V2[0] = "TIT2" + str;
                }
                else if (FramID.CompareTo("TPE1") == 0)
                {
                    ID3V2[1] = "TPE1" + str;
                }
                else if (FramID.CompareTo("TALB") == 0)
                {
                    ID3V2[2] = "TALB" + str;
                }
                else if (FramID.CompareTo("TIME") == 0)
                {
                    ID3V2[3] = "TYER" + str;
                }
                else if (FramID.CompareTo("COMM") == 0)
                {
                    ID3V2[4] = "COMM" + str;
                }
                else if (FramID.CompareTo("APIC") == 0)
                {
                    Console.WriteLine("有图片信息");

                    int i = 0;
                    while (true)
                    {

                        if (255 == bFrame[i] && 216 == bFrame[i + 1])
                        {
                            //在
                            break;

                        }
                        i++;
                    }

                    try
                    {
                        byte[] imge = new byte[frmSize - i];
                        fs.Seek(-frmSize + i, SeekOrigin.Current);
                        fs.Read(imge, 0, imge.Length);
                        MemoryStream ms = new MemoryStream(imge);

                        System.Drawing.Image img = System.Drawing.Image.FromStream(ms);

                        FileStream save = new FileStream($"{System.IO.Directory.GetCurrentDirectory()}\\专辑封面.jpeg", FileMode.Create);
                        img.Save(save, System.Drawing.Imaging.ImageFormat.Jpeg);
                        save.Close();
                        save.Dispose();
                        img.Dispose();

                        BinaryReader binReader = new BinaryReader(File.Open($"{System.IO.Directory.GetCurrentDirectory()}\\专辑封面.jpeg", FileMode.Open));
                        FileInfo fileInfo = new FileInfo($"{System.IO.Directory.GetCurrentDirectory()}\\专辑封面.jpeg");
                        byte[] bytes = binReader.ReadBytes((int)fileInfo.Length);
                        binReader.Close();
                        BitmapImage bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = new MemoryStream(bytes);
                        bitmap.EndInit();
                        背景图像.Source = bitmap;
                    }
                    catch
                    {
                        Console.WriteLine("读取图片时发生未知错误");
                        应用默认专辑图();
                    }

                    //}
                }
                else
                {
                    应用默认专辑图();
                }


            }
            return ID3V2;
        }

        public string GetFrameInfoByEcoding(byte[] b, byte conde, int length)
        {
            string str = "";
            switch (conde)
            {
                case 0:
                    str = Encoding.GetEncoding("ISO-8859-1").GetString(b, 1, length);
                    break;
                case 1:
                    str = Encoding.GetEncoding("UTF-16LE").GetString(b, 1, length);
                    break;
                case 2:
                    str = Encoding.GetEncoding("UTF-16BE").GetString(b, 1, length);
                    break;
                case 3:
                    str = Encoding.UTF8.GetString(b, 1, length);
                    break;
            }
            return str;
        }

        public async void 重置状态()
        {
            if (器材.读取器组.Count >= 1)
            {
                信息.仍需读取流 = false;

                while (信息.仍需读取流 == false)
                {

                }
            }
            
            this.Dispatcher.Invoke((ThreadStart)delegate ()
            {
                信息.提示窗打开 = false;
                底部信息.Text = "";

                信息.章节信息.Clear();
                背景图像.Source = null;
                信息.播放状态 = 音频信息.音频状态.未定义;
                信息.淡出_字节修改量 = 0;
                信息.当前段编号 = 0;
                信息.播完停止 = false;
                信息.淡入_字节修改量 = 0;
                信息.偏移 = 0;
                手动停止 = true;
                MP3文件 = false;
                播放按钮.IsEnabled = false;
                停止按钮.IsEnabled = false;
                器材.播放器组[信息.线程号].Stop();
                器材.播放器组[信息.线程号] = new WaveOutEvent();
                try
                {
                    器材.读取器组.Clear();
                }
                catch
                {
                    try
                    {
                        器材.读取器组[信息.线程号 - 1] = null;
                    }
                    catch
                    {

                    }
                }
                if (流.文件.Count > 0)
                {
                    if (流.文件[信息.线程号].过渡播放器 != null)
                    {
                        流.文件[信息.线程号].过渡播放器 = new WaveOut();
                        流.文件[信息.线程号].过渡播放器.Stop();
                    }

                    if (流.文件[信息.线程号].内存文件组 != null)
                    {
                        流.文件[信息.线程号].内存文件组.Clear();
                        流.文件[信息.线程号].读取器组.Clear();
                        流.文件[信息.线程号].obb读取器组.Clear();

                    }
                    流.文件[信息.线程号].过渡音频 = null;
                    if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                    {
                        流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                        流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                    }
                }

                信息.循环次数 = 0;
                信息.下一段编号 = 0;
                信息.当前段编号 = 0;
                播放按钮.IsEnabled = false;
                停止按钮.IsEnabled = false;
                播放列表.Clear();
                循环文件下标.Clear();
                节拍特例.Clear();
                手动停止 = true;
                MP3文件 = false;


            });

        }
        public void 更新按钮状态()
        {
            if (信息.循环方法 == 音频信息.循环类型.不可循环)
            {
                切场按钮.IsEnabled = false;
            }
            if (信息.循环方法 == 音频信息.循环类型.交互式无缝循环)
            {
                切场按钮.IsEnabled = true;
            }
            if (信息.循环方法 == 音频信息.循环类型.仅无缝循环)
            {
                切场按钮.IsEnabled = false;
            }

        }
        public void 更新文件列表(string 文件夹路径)
        {

            //清空上次文件信息
            文件名.Clear();
            对应表.Clear();
            过渡文件.Clear();
            配置文件.Clear();
            UI对应表.Clear();
            文件夹名称组.Clear();
            文件夹路径组.Clear();
            当前文件夹路径 = 文件夹路径;
            //更新文件夹信息
            文件浏览器路径.Text = Path.GetFileName(文件夹路径);
            if (Directory.Exists(文件夹路径) == false)
            {
                MessageBox.Show("不存在该文件夹，也可能是权限不组无法读取", "读取失败");
                return;
            }
            //清理表单
            文件浏览器.Items.Clear();
            文件夹名称组.Clear();
            文件夹路径组.Clear();
            string[] 文件夹组 = null;
            try
            {
                文件夹组 = Directory.GetDirectories(文件夹路径);
            }
            catch
            {
                MessageBox.Show("您所打开的文件需要更高的权限才能浏览", "权限不足");
                return;
            }
            //将文件夹信息写入内存 
            foreach (string 完整路径 in 文件夹组)
            {
                文件夹路径组.Add(完整路径);
                文件夹名称组.Add(图标按钮.形成图文(图标按钮.文件集, Path.GetFileName(完整路径)));
            }
            //在界面更新文件夹信息
            foreach (string 文件夹名称 in 文件夹名称组)
            {
                文件浏览器.Items.Add(文件夹名称);
            }

            //补丁文件夹路径
            文件夹路径 += "\\";
            //开始更新音乐信息
            //不是文件夹路径则开始判断是否有音乐
            var ogg文件列表 = Directory.GetFiles(文件夹路径, "*.ogg");
            var MP3文件列表 = Directory.GetFiles(文件夹路径, "*.mp3");

            //将文件信息载入内存
            foreach (string 文件完整路径 in ogg文件列表)
            {
                var 文件1 = Path.GetFileName(文件完整路径);
                var 曲名 = 文件1.Split(' ')[0];
                if (文件名.Contains(曲名) == false)
                {
                    文件名.Add(曲名);
                    对应表.Add(曲名, 文件完整路径);
                    Console.WriteLine($"探测1 {文件夹路径}{曲名} 过渡效果.mp3");
                    if (File.Exists($"{文件夹路径}{曲名} 过渡效果.mp3"))
                    {

                        过渡文件.Add(曲名, $"{文件夹路径}{曲名} 过渡效果.mp3");
                    }
                    if (File.Exists($"{文件夹路径}{曲名} 配置.txt"))
                    {
                        配置文件.Add(曲名, $"{文件夹路径}{曲名} 配置.txt");
                    }
                }
                else
                {
                    string 数据 = 对应表[曲名];
                    数据 += "^" + 文件完整路径;
                    对应表[曲名] = 数据;
                }

            }
            Console.WriteLine("音乐目录");
            foreach (string 曲名 in 文件名)
            {

                string[] 文件组 = 对应表[曲名].Split('^');
                Console.WriteLine($"*---{曲名}---*");
                Console.WriteLine("     该文件集下的子文件");
                foreach (string 文件2 in 文件组)
                {
                    //浏览子文件
                    Console.WriteLine(文件2);
                }
                Console.WriteLine("     该文件集下的过渡文件");
                if (过渡文件.ContainsKey(曲名))
                {
                    //浏览过渡文件

                    Console.WriteLine($"          {过渡文件[曲名]}");

                }
                if (File.Exists($"{文件夹路径}{曲名} 配置.txt"))
                {
                    文件浏览器.Items.Add(图标按钮.形成图文(图标按钮.可操作, 曲名));
                    UI对应表.Add(图标按钮.形成图文(图标按钮.可操作, 曲名), $"{曲名}");
                }
                else
                {
                    文件浏览器.Items.Add(图标按钮.形成图文(图标按钮.永续, 曲名));
                    UI对应表.Add(图标按钮.形成图文(图标按钮.永续, 曲名), $"{曲名}");
                }
            }

            //浏览MP3
            foreach (string i in MP3文件列表)
            {
                var 曲名 = Path.GetFileName(i);
                文件浏览器.Items.Add(图标按钮.形成图文(图标按钮.普通, 曲名));
                try
                {
                    UI对应表.Add(图标按钮.形成图文(图标按钮.普通, 曲名), $"{文件夹路径}{曲名}");
                }
                catch
                { }
                文件名.Add(i);
                对应表.Add(曲名, i);
            }

        }
        public MainWindow(时钟壁纸应用.主要窗口.窗口状态 状态)
        {
            控件 = 状态;
            WaveOutEvent 播放器 = new WaveOutEvent();
            器材.播放器组.Add(播放器);
            //器材与信息置入
            循环文件下标 = 信息.循环文件下标;
            节拍特例 = 信息.节拍特例;
            InitializeComponent();

            应用默认专辑图();
            底部信息.Text = "";
            更新文件列表(System.Environment.GetFolderPath(Environment.SpecialFolder.MyMusic));
            播放按钮.IsEnabled = false;
            停止按钮.IsEnabled = false;
        }




        public void 音乐判断()
        {
            //判断是否有选中项，否则取消
            if (文件浏览器.SelectedIndex == -1)
            {
                return;
            }
            //若有则判断是文件夹路径还是文件路径
            int[] 文件夹选项区间 = { 0, 文件夹路径组.Count - 1 };
            if (文件夹路径组.Count < 0)
            {
                文件夹选项区间[0] = 文件夹选项区间[1] = -1;
            }
            //是文件路径则不执行任何操作，然后退出
            if (文件浏览器.SelectedIndex >= 文件夹选项区间[0] && 文件浏览器.SelectedIndex <= 文件夹选项区间[1])
            {
                更新文件列表(文件夹路径组[文件浏览器.SelectedIndex].ToString());
                修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.None);
                return;
            }

            //清理并退出
            //如果为暂停状态下，不这样会出bug，如果有时间再重构成复用，现在就先这样
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
            {

                重置状态();
            }
            else
            {
                this.Dispatcher.Invoke((ThreadStart)delegate ()
                {

                    底部信息.Text = "";

                    信息.章节信息.Clear();

                    信息.播放状态 = 音频信息.音频状态.未定义;
                    信息.淡出_字节修改量 = 0;
                    信息.当前段编号 = 0;
                    信息.播完停止 = false;
                    信息.淡入_字节修改量 = 0;
                    手动停止 = true;
                    MP3文件 = false;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    器材.播放器组[信息.线程号].Stop();
                    器材.播放器组[信息.线程号] = new WaveOutEvent();
                    try
                    {
                        器材.读取器组.Clear();
                    }
                    catch
                    {
                        try
                        {
                            器材.读取器组[信息.线程号 - 1] = null;
                        }
                        catch
                        {

                        }
                    }
                    if (流.文件.Count > 0)
                    {
                        if (流.文件[信息.线程号].过渡播放器 != null)
                        {
                            流.文件[信息.线程号].过渡播放器 = new WaveOut();
                            流.文件[信息.线程号].过渡播放器.Stop();
                        }

                        if (流.文件[信息.线程号].内存文件组 != null)
                        {
                            流.文件[信息.线程号].内存文件组.Clear();
                            流.文件[信息.线程号].读取器组.Clear();
                            流.文件[信息.线程号].obb读取器组.Clear();

                        }
                        流.文件[信息.线程号].过渡音频 = null;
                        if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                        {
                            流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                            流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                        }
                    }

                    信息.循环次数 = 0;
                    信息.下一段编号 = 0;
                    信息.当前段编号 = 0;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    播放列表.Clear();
                    循环文件下标.Clear();
                    节拍特例.Clear();
                    手动停止 = true;
                    MP3文件 = false;


                });
            }



            信息.仍需读取流 = true;

            //用户是否选择了MP3
            if (文件浏览器.SelectedItem.ToString().Contains("mp3"))
            {
                MP3文件 = true;
                MP3读取器 = new AudioFileReader(UI对应表[文件浏览器.SelectedItem.ToString()]);

                //取封面
                ReadMp3(UI对应表[文件浏览器.SelectedItem.ToString()]);



                器材.播放器组[信息.线程号].Init(MP3读取器);
                器材.播放器组[信息.线程号].Play();

                播放按钮.Content = "I I";
                播放按钮.IsEnabled = true;
                停止按钮.IsEnabled = true;
                // 读取MP3信息
                string file = UI对应表[文件浏览器.SelectedItem.ToString()];
                ShellClass sh = new ShellClass();
                Folder dir = sh.NameSpace(Path.GetDirectoryName(file));
                FolderItem item = dir.ParseName(Path.GetFileName(file));
                string str = dir.GetDetailsOf(item, 21); // 获取歌曲时长。
                音乐名称.Text = str;


                手动停止 = false;
                信息.循环方法 = 音频信息.循环类型.不可循环;
                Thread 刷新界面1 = new Thread(刷新MP3界面信息);
                刷新界面1.Start();
                更新按钮状态();
                修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.None);
                return;
            }

            //用户选择的主题
            string 选择曲名 = 文件浏览器.SelectedItem.ToString().Split(' ')[1];
            if (文件浏览器.SelectedItem.ToString().Split(' ')[0] == "♾️")
            {
                信息.循环方法 = 音频信息.循环类型.仅无缝循环;
            }
            if (文件浏览器.SelectedItem.ToString().Split(' ')[0] == "🔃")
            {
                信息.循环方法 = 音频信息.循环类型.交互式无缝循环;
            }
            Console.WriteLine(选择曲名 + $"{信息.循环方法.ToString()}");
            更新按钮状态();
            //开始执行播放操作
            //读取需要播放的文件路径
            播放列表.Clear();
            Console.WriteLine($"播放列表被清空，当前文件数{播放列表.Count}");
            string[] 文件集 = 对应表[UI对应表[文件浏览器.SelectedItem.ToString()]].Split('^');
            foreach (string 文件3 in 文件集)
            {
                播放列表.Add(文件3);

            }
            //读取设置
            读配置文件 功能 = new 读配置文件();
            if (配置文件.ContainsKey(选择曲名) == false)
            {
                配置文件.Add(选择曲名, "未知路径");
            }

            信息.当前段BPM = Convert.ToInt32(功能.读配置项(配置文件[选择曲名], "默认配置", "BPM", "60"));
            信息.当前段拍数 = Convert.ToInt32(功能.读配置项(配置文件[选择曲名], "默认配置", "节拍", "4"));
            for (int i = 0; i < 播放列表.Count; i++)
            {
                信息.节拍特例.Add(信息.当前段拍数);
            }
            string 设置_循环文件下标 = 功能.读配置项(配置文件[选择曲名], "循环", "循环文件下标", "1");
            string[] 循环文件下标原文本 = 设置_循环文件下标.Split(',');
            foreach (string 下标值 in 循环文件下标原文本)
            {
                信息.循环文件下标.Add(Convert.ToInt32(下标值));
                Console.WriteLine($"将会循环{Convert.ToInt32(下标值)}");
            }
            string 设置_节拍特例 = 功能.读配置项(配置文件[选择曲名], "节拍特例", "节拍特例", "错误");
            var 节拍特例组 = 设置_节拍特例.Split('|');
            foreach (string 节拍特例原文本 in 节拍特例组)
            {
                if (设置_节拍特例 == "错误")
                {
                    break;
                }
                var 分隔组 = 节拍特例原文本.Split(',');
                try
                {
                    信息.节拍特例[Convert.ToInt32(分隔组[0])] = Convert.ToInt32(分隔组[1]);
                }
                catch
                {
                    MessageBox.Show("设置文件出现问题，请检查");
                    return;
                }
                Console.WriteLine($"在文件{Convert.ToInt32(分隔组[0])}将会以{Convert.ToInt32(分隔组[1])}拍进行");
            }
            string 设置_段落名 = 功能.读配置项(配置文件[选择曲名], "段落名称", "名称", "错误");
            var 段落名组 = 设置_段落名.Split('|');
            foreach (string 段落名原文本 in 段落名组)
            {
                if (设置_节拍特例 == "错误")
                {
                    break;
                }
                信息.章节信息.Add(段落名原文本);
                Console.WriteLine($"添加段落{段落名原文本}");
            }
            信息.循环次数 = 0;
            音频流 文件流 = new 音频流();
            流.文件.Add(文件流);
            WaveOutEvent 新播放器 = new WaveOutEvent();
            器材.播放器组.Add(新播放器);
            //在读取新音频时新建线程
            if (信息.线程号 != 流.文件.Count - 1)
            {
                Console.WriteLine($"当前线程{信息.线程号}不等于{流.文件.Count - 1}");
                信息.线程号 = 流.文件.Count - 1;
                Console.WriteLine($"已强行赋值为{信息.线程号}");
            }
            流.文件[信息.线程号].读入音频流(播放列表, 器材, 信息, 流, 底部信息);
            if (过渡文件.ContainsKey(选择曲名))
            {
                信息.有过渡音频 = true;
                流.文件[信息.线程号].设置过渡文件(过渡文件[选择曲名]);
            }
            else
            {
                信息.有过渡音频 = false;
            }

            器材.播放器组[信息.线程号].Play();
            播放按钮.Content = "I I";
            播放按钮.IsEnabled = true;

            停止按钮.IsEnabled = true;
            if (选择曲名.Length >= 10)
            {
                音乐名称.Text = 选择曲名.Substring(0, 9) + "...";
            }
            else { 音乐名称.Text = 选择曲名; }
            应用默认专辑图();

            Thread 刷新界面 = new Thread(刷新界面信息);
            刷新界面.Start();
            修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.None);
        }

        public void 应用默认专辑图()
        {
            //专辑图片判断器
            BinaryReader binReader = new BinaryReader(File.Open(@"..\\..\\Resources\\deficon.jpg", FileMode.Open));
            FileInfo fileInfo = new FileInfo(@"..\\..\\Resources\\deficon.jpg");
            byte[] bytes = binReader.ReadBytes((int)fileInfo.Length);
            binReader.Close();
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.StreamSource = new MemoryStream(bytes);
            bitmap.EndInit();
            背景图像.Source = bitmap;

        }

        public void 打开播放提示窗()
        {
            if (信息.提示窗打开 == true) { return; }
            信息.提示窗打开 = true;
            时钟壁纸应用.播放器窗口.播放内容提示 提示 = new 时钟壁纸应用.播放器窗口.播放内容提示($"{音乐名称.Text} | {信息.循环次数} 循环",信息);
            提示.Show();
        }

        public void 刷新MP3界面信息()
        {

            while (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing && 信息.循环方法 == 音频信息.循环类型.不可循环)
            {

                var 已播放毫秒数 = MP3读取器.Position * 1000.0 / MP3读取器.WaveFormat.BitsPerSample / MP3读取器.WaveFormat.Channels * 8.0 / MP3读取器.WaveFormat.SampleRate;
                var 当前播放时长 = TimeSpan.FromMilliseconds(已播放毫秒数);
                this.Dispatcher.Invoke((ThreadStart)delegate ()
                {
                   
                    修改任务栏状态("", (double)MP3读取器.Position / (double)MP3读取器.Length, System.Windows.Shell.TaskbarItemProgressState.Normal);
                    播放时长.Text = $"已播放 {当前播放时长.Minutes}:{当前播放时长.Seconds}";
                    if (当前播放时长.Minutes == 当前播放时长.Seconds && 当前播放时长.Seconds == 0) 
                    {
                        打开播放提示窗();
                    }
                });
                Thread.Sleep(100);

            }
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Stopped && 手动停止 == false)
            {

                MP3读取器.Position = 0;
                器材.播放器组[信息.线程号].Play();

                刷新MP3界面信息();
            }

        }
        public void 刷新界面信息()
        {

            lock (this)
            {
                //判断是否是不需要高精度切换的音乐
                if (信息.循环方法 == 音频信息.循环类型.仅无缝循环)
                {

                    while (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing && 信息.循环方法 == 音频信息.循环类型.仅无缝循环)
                    {

                        if (信息.播完停止 == true)
                        {
                            Console.WriteLine("truetoki" + 信息.当前播放位置);
                            var 已播放毫秒数 = 信息.当前播放位置 * 1000.0 / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.BitsPerSample / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.Channels * 8.0 / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.SampleRate;
                            var 当前播放时长 = TimeSpan.FromMilliseconds(已播放毫秒数);
                            this.Dispatcher.Invoke((ThreadStart)delegate ()
                            {
                                修改任务栏状态("", (double)器材.读取器组[信息.当前段编号].Position / (double)器材.读取器组[信息.当前段编号].Length, System.Windows.Shell.TaskbarItemProgressState.Normal);
                                播放时长.Text = $"已播放 {当前播放时长.Minutes}:{当前播放时长.Seconds} | 最后循环";
                            });
                            Thread.Sleep(100);
                        }
                        else
                        {

                            double 已播放毫秒数;
                            try
                            {

                                已播放毫秒数 = 器材.读取器组[信息.当前段编号].Position * 1000.0 / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.BitsPerSample / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.Channels * 8.0 / 流.文件[信息.线程号].读取器组[信息.当前段编号].WaveFormat.SampleRate;
                            }
                            catch
                            {

                                已播放毫秒数 = 0;
                            }
                            var 当前播放时长 = TimeSpan.FromMilliseconds(已播放毫秒数);
                            this.Dispatcher.Invoke((ThreadStart)delegate ()
                            {
                                当前播放时长 = TimeSpan.FromMilliseconds(已播放毫秒数);
                                try
                                {
                                    修改任务栏状态("", (double)器材.读取器组[信息.当前段编号].Position / (double)器材.读取器组[信息.当前段编号].Length, System.Windows.Shell.TaskbarItemProgressState.Normal);
                                }
                                catch
                                {
                                    Console.WriteLine("正在播放MP3，节拍刷新停止");
                                }
                                播放时长.Text = $"已播放 {当前播放时长.Minutes}:{当前播放时长.Seconds} | 已循环 {信息.循环次数}次";
                                if (当前播放时长.Minutes == 当前播放时长.Seconds && 当前播放时长.Seconds == 0)
                                {
                                    打开播放提示窗();
                                }
                            });

                            Thread.Sleep(100);
                        }
                    }

                }
                else
                {
                    try
                    {
                        while (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
                        {


                            if (信息.播完停止 == true)
                            {
                                this.Dispatcher.BeginInvoke((ThreadStart)delegate ()
                                {
                                    //更新用户定义的章节信息
                                    修改任务栏状态("", (double)器材.读取器组[信息.当前段编号].Position / (double)器材.读取器组[信息.当前段编号].Length, System.Windows.Shell.TaskbarItemProgressState.Paused);
                                    底部信息.Text = 信息.章节信息[信息.当前段编号].ToString();
                                    播放时长.Text = $"{信息.当前小节}小节 {信息.当前拍 + 1}拍 | 最后循环";
                                    if (信息.循环文件下标.Contains(信息.当前段编号)) { 切场按钮.IsEnabled = true; } else { 切场按钮.IsEnabled = false; }
                                    if (信息.当前小节 == 信息.当前拍 && 信息.当前拍 == 0)
                                    {
                                        打开播放提示窗();
                                    }
                                });
                                Thread.Sleep(100);
                            }
                            else
                            {


                                this.Dispatcher.BeginInvoke((ThreadStart)delegate ()
                                {
                                    try
                                    {
                                        修改任务栏状态("", (double)器材.读取器组[信息.当前段编号].Position / (double)器材.读取器组[信息.当前段编号].Length, System.Windows.Shell.TaskbarItemProgressState.Normal);
                                    }
                                    catch
                                    {
                                        修改任务栏状态("", 1, System.Windows.Shell.TaskbarItemProgressState.Error);
                                    }
                                    //更新用户定义的章节信息
                                    try
                                    {
                                        底部信息.Text = 信息.章节信息[信息.当前段编号].ToString();
                                        播放时长.Text = $"{信息.当前小节}小节 {信息.当前拍 + 1}拍 | 循环次数:{信息.循环次数}";
                                        if (信息.当前小节 == 信息.当前拍 && 信息.当前拍 == 0)
                                        {
                                            打开播放提示窗();
                                        }
                                        if (信息.循环文件下标.Contains(信息.当前段编号)) { 切场按钮.IsEnabled = true; } else { 切场按钮.IsEnabled = false; }
                                    }
                                    catch
                                    {
                                        Console.WriteLine("用户选择了新的音乐");
                                        修改任务栏状态("", 信息.当前拍 + 1 / 信息.当前段拍数, System.Windows.Shell.TaskbarItemProgressState.None);
                                        if (信息.当前小节 == 信息.当前拍 && 信息.当前拍 == 0)
                                        {
                                            打开播放提示窗();
                                        }
                                        return;
                                    }
                                });
                                Thread.Sleep(100);
                            }

                        }
                        if (信息.当前UI绑定线程 != 信息.线程号)
                        {
                            Thread.Sleep(1000);
                            信息.当前UI绑定线程 = 信息.线程号;
                            刷新界面信息();
                        }
                    }
                    catch
                    {
                        修改任务栏状态("", 信息.当前拍 + 1 / 信息.当前段拍数, System.Windows.Shell.TaskbarItemProgressState.None);
                        return;
                    }
                }
            }
            try
            {
                修改任务栏状态("", 信息.当前拍 + 1 / 信息.当前段拍数, System.Windows.Shell.TaskbarItemProgressState.None);
            }
            catch
            {
                Console.WriteLine("任务栏更新出现故障");
            }
        }

        private void 文件浏览器_MouseDown(object sender, MouseButtonEventArgs e)
        {

        }

        private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {

        }
        public void 修改任务栏状态(string 文字, double 数字, System.Windows.Shell.TaskbarItemProgressState 状态)
        {
            try
            {
                TaskbarItemInfo.ProgressState = 状态;
                TaskbarItemInfo.ProgressValue = 数字;
                if (正在拖动进度条 == false)
                {
                    进度条.Value = 数字;
                }
            }
            catch
            {

            }
        }
        private void 文件浏览器_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Right)
            {
                return;
            }

            修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.Indeterminate);

            if (文件浏览器.SelectedItem == null)
            {
                return;
            }
            if (文件浏览器.SelectedItem.ToString().Contains("mp3"))
            {
                MP3文件 = true;
            }

            音乐判断();

        }



        private void 切场按钮_Click(object sender, RoutedEventArgs e)
        {
            切场按钮.IsEnabled = false;
            if (信息.当前拍 + 1 == 信息.当前段拍数)
            {
                信息.切换点在末拍 = true;
            }
            TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
            //如果是一个循环中，查看用户是否准备跳过本次循环，如果是但没有下一个文件，则此次播放完毕后停止播放
            if (信息.章节信息.Count - 1 == 信息.当前段编号)
            {

                信息.播完停止 = true;
                return;

            }

            Console.WriteLine("强制下一个文件");

            流.文件[信息.线程号].设定下一文件(true, true, true);


            if (流.文件[信息.线程号].过渡音频 != null && 信息.当前段拍数 == 3)
            {
                流.文件[信息.线程号].过渡播放器.Play();

            }
            else
            {
                信息.等待效果音 = true;
            }
        }

        private void 停止按钮_Click(object sender, RoutedEventArgs e)
        {
            TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
            {
                重置状态();
            }
            else
            {
                //删掉这里来复用的话会出bug
                this.Dispatcher.Invoke((ThreadStart)delegate ()
                {

                    底部信息.Text = "";

                    信息.章节信息.Clear();

                    信息.播放状态 = 音频信息.音频状态.未定义;
                    信息.淡出_字节修改量 = 0;
                    信息.当前段编号 = 0;
                    信息.播完停止 = false;
                    信息.淡入_字节修改量 = 0;
                    手动停止 = true;
                    MP3文件 = false;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    器材.播放器组[信息.线程号].Stop();
                    器材.播放器组[信息.线程号] = new WaveOutEvent();
                    try
                    {
                        器材.读取器组.Clear();
                    }
                    catch
                    {
                        try
                        {
                            器材.读取器组[信息.线程号 - 1] = null;
                        }
                        catch
                        {

                        }
                    }
                    if (流.文件.Count > 0)
                    {
                        if (流.文件[信息.线程号].过渡播放器 != null)
                        {
                            流.文件[信息.线程号].过渡播放器 = new WaveOut();
                            流.文件[信息.线程号].过渡播放器.Stop();
                        }

                        if (流.文件[信息.线程号].内存文件组 != null)
                        {
                            流.文件[信息.线程号].内存文件组.Clear();
                            流.文件[信息.线程号].读取器组.Clear();
                            流.文件[信息.线程号].obb读取器组.Clear();

                        }
                        流.文件[信息.线程号].过渡音频 = null;
                        if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                        {
                            流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                            流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                        }
                    }

                    信息.循环次数 = 0;
                    信息.下一段编号 = 0;
                    信息.当前段编号 = 0;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    播放列表.Clear();
                    循环文件下标.Clear();
                    节拍特例.Clear();
                    手动停止 = true;
                    MP3文件 = false;


                });


            }
            信息.仍需读取流 = false;
            手动停止 = true;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

        private void 播放按钮_Click(object sender, RoutedEventArgs e)
        {
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Paused)
            {
                播放按钮.Content = "I I";
                器材.播放器组[信息.线程号].Play();
                if (MP3文件)
                {
                    Thread 刷新界面1 = new Thread(刷新MP3界面信息);
                    刷新界面1.Start();
                    手动停止 = false;
                    return;
                }
                Thread 刷新界面 = new Thread(刷新界面信息);
                刷新界面.Start();
                return;
            }
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
            {
                播放按钮.Content = "▶️";
                器材.播放器组[信息.线程号].Pause();
                TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Paused;
                return;
            }
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Stopped)
            {
                TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
                播放按钮.Content = "▶️";
                播放按钮.IsEnabled = false;
                return;
            }
        }

        private void 选文件夹按钮_Click(object sender, RoutedEventArgs e)
        {
            旧式.FolderBrowserDialog 目录选择 = new 旧式.FolderBrowserDialog();
            目录选择.Description = "选择文件夹所在目录";                         //目录对话框的描述字符串
            目录选择.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);                             //自定义从哪个目录下面选择
            目录选择.ShowNewFolderButton = true;                        //是否显示目录对话框左下角的“新建文件夹”按钮， true：显示， false： 隐藏
            目录选择.ShowDialog();
            更新文件列表(目录选择.SelectedPath);
        }

        private void 文件浏览器_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {

        }

        private void 文件浏览器_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
        {

        }

        private void Slider_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {

        }

        private void Slider_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {

        }

        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            器材.播放器组[信息.线程号].Volume = (float)(音量滑块.Value / 100);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //清理并退出
            控件.播放器打开状态 = false;
            控件.当前播放器 = null;
            //如果为暂停状态下，不这样会出bug，如果有时间再重构成复用，现在就先这样
            if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
            {

                重置状态();
            }
            else
            {
                this.Dispatcher.Invoke((ThreadStart)delegate ()
                {

                    底部信息.Text = "";

                    信息.章节信息.Clear();

                    信息.播放状态 = 音频信息.音频状态.未定义;
                    信息.淡出_字节修改量 = 0;
                    信息.当前段编号 = 0;
                    信息.播完停止 = false;
                    信息.淡入_字节修改量 = 0;
                    手动停止 = true;
                    MP3文件 = false;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    器材.播放器组[信息.线程号].Stop();
                    器材.播放器组[信息.线程号] = new WaveOutEvent();
                    try
                    {
                        器材.读取器组.Clear();
                    }
                    catch
                    {
                        try
                        {
                            器材.读取器组[信息.线程号 - 1] = null;
                        }
                        catch
                        {

                        }
                    }
                    if (流.文件.Count > 0)
                    {
                        if (流.文件[信息.线程号].过渡播放器 != null)
                        {
                            流.文件[信息.线程号].过渡播放器 = new WaveOut();
                            流.文件[信息.线程号].过渡播放器.Stop();
                        }

                        if (流.文件[信息.线程号].内存文件组 != null)
                        {
                            流.文件[信息.线程号].内存文件组.Clear();
                            流.文件[信息.线程号].读取器组.Clear();
                            流.文件[信息.线程号].obb读取器组.Clear();

                        }
                        流.文件[信息.线程号].过渡音频 = null;
                        if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                        {
                            流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                            流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                        }
                    }

                    信息.循环次数 = 0;
                    信息.下一段编号 = 0;
                    信息.当前段编号 = 0;
                    播放按钮.IsEnabled = false;
                    停止按钮.IsEnabled = false;
                    播放列表.Clear();
                    循环文件下标.Clear();
                    节拍特例.Clear();
                    手动停止 = true;
                    MP3文件 = false;


                });
            }

            while (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
            {

                器材.播放器组[信息.线程号].Stop();
                器材.播放器组[信息.线程号] = new WaveOutEvent();
                foreach (var i in 器材.播放器组)
                {
                    i.Dispose();
                }
                if (流.文件.Count != 0)
                {
                    流.文件[信息.线程号].过渡播放器 = new WaveOut();
                    流.文件[信息.线程号].过渡播放器.Stop();
                    流.文件[信息.线程号].内存文件组.Clear();
                    流.文件[信息.线程号].读取器组.Clear();
                    流.文件[信息.线程号].obb读取器组.Clear();
                    Console.WriteLine(流.文件[信息.线程号].内存文件组.Count);
                    if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                    {
                        流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                        流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                    }
                }
                else
                {
                    MP3读取器.Dispose();

                }
                信息.仍需读取流 = false;
                信息.循环次数 = 0;
              
                信息.下一段编号 = 0;
                信息.当前段编号 = 0;
                播放按钮.IsEnabled = false;
                停止按钮.IsEnabled = false;
                播放列表.Clear();
                循环文件下标.Clear();
                节拍特例.Clear();

            }
            信息.仍需读取流 = true;

        }

        private void 文件夹上级按钮_Click(object sender, RoutedEventArgs e)
        {
            DirectoryInfo pathInfo = new DirectoryInfo(当前文件夹路径);
            try
            {
                if (pathInfo.Parent.FullName == null)
                {
                    MessageBox.Show("没有更上一级的文件夹，或许应该按浏览选择其他磁盘");
                }
                string newPath = pathInfo.Parent.FullName;
                更新文件列表(newPath);
            }
            catch
            {
                return;
            }
        }

        private void 测试按钮_Click(object sender, RoutedEventArgs e)
        {
            修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.Indeterminate);

            if (文件浏览器.SelectedItem == null)
            {
                return;
            }
            if (文件浏览器.SelectedItem.ToString().Contains("mp3"))
            {
                MP3文件 = true;
            }

            音乐判断();
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && 切场按钮.IsEnabled == true)
            {
                TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
                //如果是一个循环中，查看用户是否准备跳过本次循环，如果是但没有下一个文件，则此次播放完毕后停止播放
                if (信息.章节信息.Count - 1 == 信息.当前段编号)
                {

                    信息.播完停止 = true;
                    return;

                }

                Console.WriteLine("强制下一个文件");

                流.文件[信息.线程号].设定下一文件(true, true, true);


                if (流.文件[信息.线程号].过渡音频 != null && 信息.当前段拍数 == 3)
                {
                    流.文件[信息.线程号].过渡播放器.Play();

                }
                else
                {
                    信息.等待效果音 = true;
                }



            }
            if (e.Key == Key.Delete && 停止按钮.IsEnabled == true)
            {
                TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
                if (器材.播放器组[信息.线程号].PlaybackState == PlaybackState.Playing)
                {
                    重置状态();
                }
                else
                {
                    //删掉这里来复用的话会出bug
                    this.Dispatcher.Invoke((ThreadStart)delegate ()
                    {

                        底部信息.Text = "";

                        信息.章节信息.Clear();

                        信息.播放状态 = 音频信息.音频状态.未定义;
                        信息.淡出_字节修改量 = 0;
                        信息.当前段编号 = 0;
                        信息.播完停止 = false;
                        信息.淡入_字节修改量 = 0;
                        手动停止 = true;
                        MP3文件 = false;
                        播放按钮.IsEnabled = false;
                        停止按钮.IsEnabled = false;
                        器材.播放器组[信息.线程号].Stop();
                        器材.播放器组[信息.线程号] = new WaveOutEvent();
                        try
                        {
                            器材.读取器组.Clear();
                        }
                        catch
                        {
                            try
                            {
                                器材.读取器组[信息.线程号 - 1] = null;
                            }
                            catch
                            {

                            }
                        }
                        if (流.文件.Count > 0)
                        {
                            if (流.文件[信息.线程号].过渡播放器 != null)
                            {
                                流.文件[信息.线程号].过渡播放器 = new WaveOut();
                                流.文件[信息.线程号].过渡播放器.Stop();
                            }

                            if (流.文件[信息.线程号].内存文件组 != null)
                            {
                                流.文件[信息.线程号].内存文件组.Clear();
                                流.文件[信息.线程号].读取器组.Clear();
                                流.文件[信息.线程号].obb读取器组.Clear();

                            }
                            流.文件[信息.线程号].过渡音频 = null;
                            if (流.文件[信息.线程号].过渡文件音频文件读取器 != null)
                            {
                                流.文件[信息.线程号].过渡文件音频文件读取器.Close();
                                流.文件[信息.线程号].过渡文件音频文件读取器.Dispose();
                            }
                        }

                        信息.循环次数 = 0;
                        信息.下一段编号 = 0;
                        信息.当前段编号 = 0;
                        播放按钮.IsEnabled = false;
                        停止按钮.IsEnabled = false;
                        播放列表.Clear();
                        循环文件下标.Clear();
                        节拍特例.Clear();
                        手动停止 = true;
                        MP3文件 = false;


                    });


                }
                信息.仍需读取流 = false;
                手动停止 = true;

            }
            if (e.Key == Key.R)
            {
                修改任务栏状态("", 0, System.Windows.Shell.TaskbarItemProgressState.Indeterminate);

                if (文件浏览器.SelectedItem == null)
                {
                    return;
                }
                if (文件浏览器.SelectedItem.ToString().Contains("mp3"))
                {
                    MP3文件 = true;
                }

                音乐判断();

            }
        }

        private void 打开文件夹_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void 打开文件夹_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("准备打开文件夹");
            if (文件浏览器.SelectedItem == null)
            {
                Console.WriteLine("文件夹不存在");
                return;
            }

            System.Diagnostics.Process.Start(当前文件夹路径);
        }

        private void 打开文件夹_ContextMenuOpening(object sender, System.Windows.Controls.ContextMenuEventArgs e)
        {

        }

        private void 文件浏览器_ContextMenuOpening(object sender, System.Windows.Controls.ContextMenuEventArgs e)
        {
            if (文件浏览器.SelectedItem == null)
            {
                return;
            }
            if (文件浏览器.SelectedItem.ToString().Split(' ')[0] == "🔃")
            {
                新建配置文件.Visibility = Visibility.Collapsed;
                管理配置文件.Visibility = Visibility.Visible;
            }

            if (文件浏览器.SelectedItem.ToString().Split(' ')[0] == "♾️")
            {
                新建配置文件.Visibility = Visibility.Visible;
                管理配置文件.Visibility = Visibility.Collapsed;
            }

            if (文件浏览器.SelectedItem.ToString().Split(' ')[0] == "💿")
            {
                管理配置文件.Visibility = Visibility.Collapsed;
                新建配置文件.Visibility = Visibility.Collapsed;
            }
        }

        private void 管理配置文件_Click(object sender, RoutedEventArgs e)
        {

            string 选择项 = 文件浏览器.SelectedItem.ToString();
            选择项 = 选择项.Replace(选择项.Split(' ')[0] + " ", "");
            时钟.新建循环配置文件 新建配置 = new 时钟.新建循环配置文件($"{当前文件夹路径}\\{选择项} 配置.txt");
            新建配置.更新方法 = 更新文件列表;
            新建配置.Show();
        }

        private void 音量按钮_Click(object sender, RoutedEventArgs e)
        {
            if (音量工具组.IsOpen == true)
            {
                音量工具组.Visibility = Visibility.Collapsed;
                音量工具组.IsOpen = false;
            }
            else
            {
                音量工具组.Visibility = Visibility.Visible;
                音量工具组.IsOpen = true;
            }
        }

        private void 刷新_Click(object sender, RoutedEventArgs e)
        {
            更新文件列表(当前文件夹路径);
        }

        private void 进度条_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {

        }

        private void 进度条_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine($"拖动了滚动条 当前状态{进度条.Value}");
        }

        private void 进度条_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Console.WriteLine($"拖动了滚动条 当前状态{进度条.Value}");
            if (MP3文件)
            {
                MP3读取器.Position = Convert.ToInt64(MP3读取器.Length * 进度条.Value);
            }
            else
            {
                if (切场按钮.IsEnabled == true || 信息.章节信息.Count >= 1)
                {
                    var 用户选择 = MessageBox.Show("请注意，现正在进行无缝交互循环中，若要拖动进度条会导致当前节拍计算失效，您要继续么", "警告 - 节拍计算可能失效", MessageBoxButton.YesNo);
                    if (用户选择 == MessageBoxResult.No)
                    { 正在拖动进度条 = false; return; }
                }
                器材.读取器组[信息.当前段编号].Position = Convert.ToInt64(器材.读取器组[信息.当前段编号].Length * 进度条.Value);
            }
            正在拖动进度条 = false;
        }

        private void 进度条_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            正在拖动进度条 = true;
        }

        private void 搜索框_MouseDown(object sender, MouseButtonEventArgs e)
        {

        }

        private void 搜索框_GotFocus(object sender, RoutedEventArgs e)
        {
            搜索框.Text = "";
            搜索框.Background = Brushes.White;
            Console.WriteLine("已点击过");
        }

        private void 搜索框_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            搜索框.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#000000"));
            try
            {
                var query = UI对应表.Keys.Where(x => x.Contains(搜索框.Text));


                foreach (var item in query)
                {
                    文件浏览器.SelectedIndex = (文件浏览器.Items.IndexOf(item));
                    文件浏览器.ScrollIntoView(item);
                    return;

                }
            }
            catch
            { Console.WriteLine("无匹配项"); }

        }

        private void 搜索框_LostFocus(object sender, RoutedEventArgs e)
        {
            if (搜索框.Text.Length <= 0)
            {
                搜索框.Text = "🔎 | 在文件中搜索...";
                搜索框.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF565655"));
                搜索框.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFB8B8B8"));
            }
        }

        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {


            if (e.LeftButton == MouseButtonState.Pressed && 搜索框.IsFocused == false)

            {

                this.DragMove();

            }


        }

        private void 最小化_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void 关闭_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void Window_Initialized(object sender, EventArgs e)
        {


        }

        private void 隐藏_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Console.WriteLine("播放器已退出");
        }
    }
}
